home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 11 / Mac Magazin and MacEasy Magazine CD - Issue 11.iso / Sharewarebibliothek / Entwickler / WASTE 1.1b1 Distribution / Demo Source / WEDemoScripting.p < prev    next >
Text File  |  1995-06-01  |  9KB  |  308 lines

  1. unit WEDemoScripting;
  2.  
  3. { WASTE DEMO PROJECT: }
  4. { Minimal Scripting Support: }
  5. { service "get data" and "set data" events }
  6. { in which the object descriptor is "contents of selection" }
  7.  
  8. { The code in this unit is partly based on public domain code written by: }
  9. { Ed Lai, Apple Computer Inc. }
  10.  
  11. { Copyright © 1993-1995 Marco Piovanelli }
  12. { All Rights Reserved }
  13.  
  14. interface
  15.     uses
  16.         WEDemoIntf;
  17.  
  18.     function InstallCoreHandlers: OSErr;
  19.  
  20. implementation
  21.     uses
  22.         AEObjects, AERegistry;
  23.  
  24.     const
  25.  
  26.         kMaxPropLevel = 2;
  27.  
  28.     type
  29.  
  30.         PropArray = array[1..kMaxPropLevel] of DescType;
  31.  
  32.     procedure InitDesc (var desc: AEDesc);
  33.     begin
  34.         desc.descriptorType := typeNull;
  35.         desc.dataHandle := nil;
  36.     end;  { InitDesc }
  37.  
  38.     procedure ForgetDesc (var desc: AEDesc);
  39.     begin
  40.         if (desc.dataHandle <> nil) then
  41.             if (AEDisposeDesc(desc) <> noErr) then
  42.                 ;
  43.         desc.descriptorType := typeNull;
  44.         desc.dataHandle := nil;
  45.     end;  { ForgetDesc }
  46.  
  47.     function PropertyOf (var spec: AERecord;
  48.                                     var propLevel: Integer;
  49.                                     var properties: PropArray): Boolean;
  50.         var
  51.             objSpec: AERecord;
  52.             theType: DescType;
  53.             actualType: DescType;
  54.             actualSize: LongInt;
  55.             key: AEKeyword;
  56.     begin
  57.         PropertyOf := false;            { we don't know this is a property yet }
  58.         InitDesc(objSpec);
  59.  
  60. { if spec is an Apple event (propLevel = 0), use its direct object }
  61. { otherwise use 'from' parameter of object specifier }
  62.         if (propLevel = 0) then
  63.             key := keyDirectObject
  64.         else
  65.             key := keyAEContainer;
  66.  
  67. { extract object specifier }
  68.         if (AEGetParamDesc(spec, key, typeAERecord, objSpec) = noErr) then
  69.  
  70. { is this a property? -- get desired class }
  71.             if (AEGetParamPtr(objSpec, keyAEDesiredClass, typeType, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  72.                 if (theType = cProperty) then
  73.  
  74. { this is redundunt, but won't hurt to make sure }
  75.                     if (AEGetParamPtr(objSpec, keyAEKeyForm, typeEnumerated, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  76.                         if (theType = formPropertyID) then
  77.  
  78. { which property? }
  79.                             if (AEGetParamPtr(objSpec, keyAEKeyData, typeType, actualType, @theType, SizeOf(theType), actualSize) = noErr) then
  80.                                 begin
  81.  
  82. { we now know what property }
  83.                                     propLevel := propLevel + 1;
  84.                                     properties[propLevel] := theType;
  85.  
  86. { property of what? }
  87.                                     if (AESizeOfParam(objSpec, keyAEContainer, actualType, actualSize) = noErr) then
  88.                                         if (actualType = typeNull) then
  89.  
  90. { property of application, we are done }
  91.                                             PropertyOf := true
  92.  
  93.                                         else if (actualType = typeObjectSpecifier) and (propLevel < kMaxPropLevel) then
  94.  
  95. { property of another object specifier, do a recursive call if we haven't reached max level }
  96.                                             PropertyOf := PropertyOf(objSpec, propLevel, properties);
  97.                                 end;
  98.  
  99.         ForgetDesc(objSpec);
  100.  
  101.     end;  { PropertyOf }
  102.  
  103.     function HandleGetData (var ae, reply: AppleEvent;
  104.                                     refCon: LongInt): OSErr;
  105.         var
  106.             propLevel: Integer;
  107.             properties: PropArray;
  108.             window: WindowPtr;
  109.             selStart, selEnd: LongInt;
  110.             textDesc, stylesDesc, recordDesc, styledTextDesc: AEDesc;
  111.             requestedType, actualType: DescType;
  112.             actualSize: Size;
  113.  
  114.         procedure CleanUp;
  115.         begin
  116.             ForgetDesc(textDesc);
  117.             ForgetDesc(stylesDesc);
  118.             ForgetDesc(recordDesc);
  119.             ForgetDesc(styledTextDesc);
  120.         end;  { CleanUp }
  121.  
  122.         procedure CheckErr (err: OSErr);
  123.         begin
  124.             if (err <> noErr) then
  125.                 begin
  126.                     HandleGetData := err;
  127.                     CleanUp;
  128.                     Exit(HandleGetData);
  129.                 end;
  130.         end;  { CheckErr }
  131.  
  132.     begin
  133.         HandleGetData := noErr;
  134.         InitDesc(textDesc);
  135.         InitDesc(stylesDesc);
  136.         InitDesc(recordDesc);
  137.         InitDesc(styledTextDesc);
  138.  
  139. { the only Get Data phrase we support is "Get the Contents of the Selection" }
  140.         propLevel := 0;                     { 0 means we are passing in an Apple Event }
  141.         if PropertyOf(ae, propLevel, properties) & ((propLevel = 2) & (properties[1] = pContents) & (properties[2] = pSelection)) then
  142.             begin
  143.  
  144. { make sure there is a window in front }
  145.                 window := FrontWindow;
  146.                 if (window = nil) then
  147.                     CheckErr(errAENoSuchObject);
  148.  
  149. { allocate a handle to hold a temporary copy of the selection text }
  150.                 CheckErr(NewHandleTemp(0, textDesc.dataHandle));
  151.                 textDesc.descriptorType := typeChar;
  152.  
  153. { extract the keyAERequestedType parameter, if present }
  154.                 if (AEGetParamPtr(ae, keyAERequestedType, typeType, actualType, @requestedType, SizeOf(requestedType), actualSize) = noErr) then
  155.                     if (requestedType = typeStyledText) then
  156.                         begin
  157.  
  158. { our client wants styled text: }
  159. { allocate a handle to hold a temporary copy of the selection text }
  160.                             CheckErr(NewHandleTemp(0, stylesDesc.dataHandle));
  161.                             stylesDesc.descriptorType := typeScrapStyles;
  162.                         end;
  163.  
  164. { make a copy of the selection in the frontmost window }
  165.                 WEGetSelection(selStart, selEnd, DocumentPeek(window)^.hWE);
  166.                 CheckErr(WECopyRange(selStart, selEnd, textDesc.dataHandle, StScrpHandle(stylesDesc.dataHandle), nil, DocumentPeek(window)^.hWE));
  167.  
  168. { fill in the reply Apple event }
  169.                 if (stylesDesc.dataHandle = nil) then
  170.  
  171. { UNSTYLED TEXT }
  172. { put the text descriptor into the reply Apple event }
  173.                     CheckErr(AEPutParamDesc(reply, keyDirectObject, textDesc))
  174.  
  175.                 else
  176.                     begin
  177.  
  178. { STYLED TEXT }
  179. { create an Apple event record to hold text + styles }
  180.                         CheckErr(AECreateList(nil, 0, true, recordDesc));
  181.  
  182. { add the text descriptor to the record }
  183.                         CheckErr(AEPutParamDesc(recordDesc, keyAEText, textDesc));
  184.  
  185. { add the styles descriptor to the record }
  186.                         CheckErr(AEPutParamDesc(recordDesc, keyAEStyles, stylesDesc));
  187.  
  188. { coerce the record into a styled text descriptor }
  189.                         CheckErr(AECoerceDesc(recordDesc, typeStyledText, styledTextDesc));
  190.  
  191. { put the styled text descriptor into the reply Apple event }
  192.                         CheckErr(AEPutParamDesc(reply, keyDirectObject, styledTextDesc));
  193.  
  194.                     end;
  195.             end
  196.         else
  197.             CheckErr(errAENoSuchObject);
  198.  
  199. { clean up }
  200.         CleanUp;
  201.  
  202.     end;  { HandleGetData }
  203.  
  204.     function HandleSetData (var ae, reply: AppleEvent;
  205.                                     refCon: LongInt): OSErr;
  206.         var
  207.             propLevel: Integer;
  208.             properties: PropArray;
  209.             window: WindowPtr;
  210.             textDesc, stylesDesc, recordDesc, styledTextDesc: AEDesc;
  211.             dataType: DescType;
  212.             dataSize: Size;
  213.  
  214.         procedure CleanUp;
  215.         begin
  216.             ForgetDesc(textDesc);
  217.             ForgetDesc(stylesDesc);
  218.             ForgetDesc(recordDesc);
  219.             ForgetDesc(styledTextDesc);
  220.         end;  { CleanUp }
  221.  
  222.         procedure CheckErr (err: OSErr);
  223.         begin
  224.             if (err <> noErr) then
  225.                 begin
  226.                     HandleSetData := err;
  227.                     CleanUp;
  228.                     Exit(HandleSetData);
  229.                 end;
  230.         end;  { CheckErr }
  231.  
  232.     begin
  233.         HandleSetData := noErr;
  234.         InitDesc(textDesc);
  235.         InitDesc(stylesDesc);
  236.         InitDesc(recordDesc);
  237.         InitDesc(styledTextDesc);
  238.  
  239. { the only Set Data phrase we support is "Set the Contents of the Selection" }
  240.         propLevel := 0;                 { 0 means we are passing in an Apple Event }
  241.         if PropertyOf(ae, propLevel, properties) & ((propLevel = 2) & (properties[1] = pContents) & (properties[2] = pSelection)) then
  242.             begin
  243.  
  244. { make sure there is a window in front }
  245.                 window := FrontWindow;
  246.                 if (window = nil) then
  247.                     CheckErr(errAENoSuchObject);
  248.  
  249. { we expect the data parameter to be either TEXT or STXT }
  250.                 CheckErr(AESizeOfParam(ae, keyAEData, dataType, dataSize));
  251.                 if (dataType = typeStyledText) then
  252.                     begin
  253.  
  254. { STYLED TEXT }
  255. { extract styled text data from the Apple event }
  256.                         CheckErr(AEGetParamDesc(ae, keyAEData, typeStyledText, styledTextDesc));
  257.  
  258. { coerce the styled text descriptor to an Apple event record }
  259.                         CheckErr(AECoerceDesc(styledTextDesc, typeAERecord, recordDesc));
  260.  
  261. { extract text + styles from the record descriptor }
  262.                         CheckErr(AEGetParamDesc(recordDesc, keyAEText, typeChar, textDesc));
  263.                         CheckErr(AEGetParamDesc(recordDesc, keyAEStyles, typeScrapStyles, stylesDesc));
  264.                     end
  265.                 else
  266.  
  267. { UNSTYLED TEXT }
  268. { extract text data from the Apple event }
  269.                     CheckErr(AEGetParamDesc(ae, keyAEData, typeChar, textDesc));
  270.  
  271. { insert the text }
  272.                 HLock(textDesc.dataHandle);
  273.                 CheckErr(WEInsert(textDesc.dataHandle^, GetHandleSize(textDesc.dataHandle), StScrpHandle(stylesDesc.dataHandle), nil, DocumentPeek(window)^.hWE));
  274.                 HUnlock(textDesc.dataHandle);
  275.  
  276.             end
  277.         else
  278.             CheckErr(errAENoSuchObject);
  279.  
  280. { clean up }
  281.         CleanUp;
  282.  
  283.     end;  { HandleSetData }
  284.  
  285. { THINK Pascal compiler directive: put the following code in the "Init" segment }
  286. {$S Init}
  287.  
  288.     function InstallCoreHandlers: OSErr;
  289.  
  290.         procedure CheckErr (err: OSErr);
  291.         begin
  292.             if (err <> noErr) then
  293.                 begin
  294.                     InstallCoreHandlers := err;
  295.                     Exit(InstallCoreHandlers);
  296.                 end;
  297.         end;  { CheckErr }
  298.  
  299.     begin
  300.         InstallCoreHandlers := noErr;
  301.  
  302. { install Apple event handlers for the Required Suite }
  303.         CheckErr(AEInstallEventHandler(kAECoreSuite, kAEGetData, NewAEEventHandlerProc(@HandleGetData), 0, false));
  304.         CheckErr(AEInstallEventHandler(kAECoreSuite, kAESetData, NewAEEventHandlerProc(@HandleSetData), 0, false));
  305.  
  306.     end;  { InstallCoreHandlers }
  307.  
  308. end.